package com.asura.framework.rulemodel.engine;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.asura.framework.rulemodel.TreeNode;
import com.asura.framework.rulemodel.exception.TreeNodeException;

/**
 * 默认规则树节点引擎实现.
 * @author a123
 *
 */
public class DefaultRuleTreeEngine implements RuleTreeEngine
{

	/** 树根 */
	private TreeNode root = new TreeNode( "tree_root" );

	@Override
	public TreeNode getRootNode( )
	{
		TreeNode root = new TreeNode( this.root.getName( ) );
		root.setNote( "树根" );
		root.setType( 1 );
		root.setChilds( this.root.getChilds( ) );
		return root;
	}

	@Override
	public TreeNode getTreeNode( String nodeName )
	{
		if ( root.getName( ).equals( nodeName ) || nodeName == null )
		{
			return root;
		}
		TreeNode child = getTreeNode( nodeName, root );
		if ( child == null )
		{
			throw new TreeNodeException( "节点[" + nodeName + "]不存在" );
		}
		return child;
	}

	private TreeNode getTreeNode( String nodeName, TreeNode node )
	{
		List< TreeNode > childs = node.getChilds( );
		for ( TreeNode child : childs )
		{
			if ( child.getName( ).equals( nodeName ) )
			{
				return child;
			}
			TreeNode _child = getTreeNode( nodeName, child );
			if ( _child == null )
			{
				continue;
			}
			return _child;
		}
		return null;
	}

	@Override
	public List< TreeNode > getTreeNodesByGroup( String group )
	{
		List< TreeNode > result = getTreeNodesByGroup( group, root );
		return result;
	}

	private List< TreeNode > getTreeNodesByGroup( String group, TreeNode node )
	{
		List< TreeNode > childs = node.getChilds( );
		if ( childs == null )
		{
			return Collections.emptyList( );
		}

		List< TreeNode > result = new ArrayList< TreeNode >( 3 );
		for ( TreeNode n : childs )
		{
			if ( n.getGroup( ).equals( group ) )
			{
				result.add( n );
			}
			List< TreeNode > childNodes = getTreeNodesByGroup( group, n );
			result.addAll( childNodes );
		}

		return result;
	}

	@Override
	public void addTreeNode( TreeNode node )
	{
		TreeNode parent = getTreeNode( node.getFront( ) );
		parent.getChilds( ).add( node );
	}

	@Override
	public boolean contains( String nodeName )
	{
		return getTreeNode( nodeName ) != null;
	}
}
